﻿Imports Aricie.DNN.Modules.LuceneSearch.UI.FilteringControls
Imports Lucene.Net.Search
Imports Lucene.Net.Index


Namespace Aricie.DNN.Modules.LuceneSearch.UI.FilteringControls.Basic
    Public Class Alphabet
        Inherits SimpleFilteringControl

        Public Event Click(ByVal lettre As String)

        Public Overrides Property Enabled As Boolean
            Get
                If (ViewState("Enabled") IsNot Nothing) Then
                    Return DirectCast(ViewState("Enabled"), Boolean)
                End If
                Return False
            End Get
            Set(value As Boolean)
                ViewState("Enabled") = value
            End Set
        End Property

        Public Overrides ReadOnly Property Value As String
            Get
                Return FieldValue
            End Get
        End Property

        Protected Overrides Sub OnLoad(e As System.EventArgs)
            Dim alphabet As New List(Of String)({"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"})
            alphabet.ForEach(AddressOf AddControl)

            MyBase.OnLoad(e)
        End Sub

        Private Sub AddControl(letter As String)
            Dim Link As New LinkButton() With {.Text = letter, .CommandArgument = letter, .CssClass = "Normal", .Enabled = Enabled}
            AddHandler Link.Click, AddressOf Lettre_Click
            If Value = letter Then
                Link.CssClass = "NormalBold"
            End If
            pnAlpha.Controls.Add(Link)
            Dim Spacer As New HtmlGenericControl("span") With {.InnerHtml = IIf(letter = "N"c AndAlso DisplayOnTwoLines, " ", "&nbsp;").ToString()}
            pnAlpha.Controls.Add(Spacer)
        End Sub

        Public Sub Lettre_Click(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim link As LinkButton = CType(sender, LinkButton)
            link.CssClass = "NormalBold"

            FieldValue = link.CommandArgument
            RaiseEvent Click(link.CommandArgument)
            If SearchOnClick Then
                SignalFilterChanged()
            End If
        End Sub

        Protected Property FieldValue() As String
            Get
                Return CStr(ViewState("FieldValue"))
            End Get
            Set(ByVal value As String)
                ViewState("FieldValue") = value
            End Set
        End Property

        Public Property DisplayOnTwoLines() As Boolean
            Get
                Return CBool(ViewState("DisplayOnTwoLines"))
            End Get
            Set(ByVal value As Boolean)
                ViewState("DisplayOnTwoLines") = value
            End Set
        End Property

        Public Property SearchOnClick() As Boolean
            Get
                Return CBool(ViewState("SearchOnClick"))
            End Get
            Set(ByVal value As Boolean)
                ViewState("SearchOnClick") = value
            End Set
        End Property

        Public Overrides Function SetFilter() As Lucene.Net.Search.Query
            Dim BQ As New BooleanQuery()

            For Each field In FieldsList
                Dim PQ As New PrefixQuery(New Term(field, Me.FieldValue.ToLower))
                PQ.RewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE
                BQ.Add(New BooleanClause(PQ, Occur.SHOULD))
            Next

            Return BQ
        End Function

        Private Function CheckMatchingQuery(q As Query) As Boolean
            Dim Filter = Filtering.FluentFilterRulesManagerFactory.Init() _
                         .Expects(Of PrefixQuery)("Un seul champ pour Alphabet") _
                         .ExpectsComplex("Plusieurs champs", AddressOf IsBooleanQueryValid) _
                         .Create()
            Return Filter.Matches(q)
        End Function

        Private Function IsBooleanQueryValid(q As BooleanQuery) As Boolean
            For Each c As BooleanClause In q.GetClauses()
                If Not TypeOf c.Query() Is PrefixQuery Then
                    Return False
                End If
            Next
            Return True
        End Function

        Public Overrides Function ReadFilter(q As Lucene.Net.Search.Query) As Boolean
            If Not CheckMatchingQuery(q) Then
                Exit Function
            End If

            Dim Terms As HashSet(Of Term) = Business.SpecificVersionLuceneProvider.Instance().CreateHashSet(Of Term)()
            Business.SpecificVersionLuceneProvider.Instance().ExtractNativeTerm(q, Terms)

            Dim SelectedValue As String = Nothing


            For Each k As Term In Terms
                If Not FieldsList.Contains(k.Field) Then
                    Return False ' on a un champ différent de ceux qu'on est censé accepté
                End If
                If SelectedValue Is Nothing Then
                    SelectedValue = k.Text
                Else
                    If SelectedValue <> k.Text Then
                        Return False
                    End If
                End If
            Next

            FieldValue = SelectedValue

            Return True
        End Function
    End Class
End Namespace